/*
 * @Author: error: git config user.name & please set dead value or install git
 * @Date: 2022-08-31 10:26:21
 * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
 * @LastEditTime: 2023-06-14 11:12:54
 * @FilePath: \stm32g431_AllRings\applications\ws2812.h
 * @Description:
 *
 * Copyright (c) 2022 by error: git config user.name && git config user.email & please set dead value or install git, All Rights Reserved.
 */
#ifndef __WS2812_H
#define __WS2812_H

#include <rtthread.h>
#include <board.h>
#include "rtdebug.h"
#include "string.h"
#include "my_tim_drv.h" //定时器句柄

/**********************Config********************/
#define BIT_1 143 // 55 // 1比较值为61-->850us
#define BIT_0 70  // 25 // 0比较值为28-->400us

#define PIXEL_SIZE 2
#define WS28xx_PWM_hTIMER htim3
#define WS28xx_PWM_Chaneel TIM_CHANNEL_1
// #define USE_HSV_WAYS // 使用HSV颜色

#ifdef USE_HSV_WAYS
#define HSV_H_MAX 360
#define HSV_H_MIN 1

#define HSV_S_MAX 1
#define HSV_S_MIN 0.6 // 0.6保证能显示基本颜色（而不会变白色失真）

#define HSV_V_MAX 1
#define HSV_V_MIN 0.005
#endif

#define WS2812_RGB_WHITE 0XFFFFFF
#define WS2812_RGB_RED 0XFF0000 // 红色
#define WS2812_RGB_GREEN 0X00FF00
#define WS2812_RGB_BLUE 0X0000FF

// 整个WS28xx_DataTypeStruct结构体将被以PWM方式发送
typedef struct
{
    // 3个0等待PWM稳定
    uint32_t ColorStartData[3];
    // 实际GRB数据(已经转换为PWM对应的值)
    uint32_t ColorRealData[24 * PIXEL_SIZE + 60];
    // 结束位为0
    uint32_t ColorEndData;
} WS28xx_DataTypeStruct;

typedef struct
{
    // 实际发送的数据
    WS28xx_DataTypeStruct WS28xx_Data;
    // 灯数量
    unsigned short int Pixel_size;

    // 单独设置index的RGB颜色
    void (*SetPixelColor_RGB)(unsigned short int index, unsigned char r, unsigned char g, unsigned char b);
    // 从RGB数据读出：设置index的RGB颜色
    void (*SetPixelColor_From_RGB_Buffer)(unsigned short int pixelIndex, unsigned char pRGB_Buffer[][3], unsigned short int DataCount);
    // 设置所有为RGB颜色
    void (*SetALLColor_RGB)(unsigned char r, unsigned char g, unsigned char b);
    // 获取某个位置的RGB
    void (*GetPixelColor_RGB)(unsigned short int index, unsigned char *r, unsigned char *g, unsigned char *b);

#ifdef USE_HSV_WAYS
    // **************************************** HSV空间设置 ****************************************
    // 单独设置index的HSV颜色																									--->>改变HSV
    void (*SetPixelColor_HSV)(unsigned short int index, unsigned short int h, float s, float v);

    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!以下操作在原来颜色基础上做改变
    // 设置某个位置的HSV色相（Hue）（1~~360）																		--->>也就是颜色(逆时针)
    // SetPixelColor_HSV_H注意该函数，如果一开始
    void (*SetPixelColor_HSV_H)(unsigned short int pixelIndex, unsigned short int light);
    // 设置某个位置的HSV饱和度（Saturation）（0.6~~1）													--->>色彩纯净度
    void (*SetPixelColor_HSV_S)(unsigned short int pixelIndex, float light);
    // 设置某个位置的HSV明度（Value）（0.005~~1）																--->>也就是亮度
    void (*SetPixelColor_HSV_V)(unsigned short int pixelIndex, float light);

    // 设置所有HSV色相（1~~360）			       																			--->>也就是颜色(逆时针)
    void (*SetALLColor_HSV_H)(unsigned short int setH);
    // 设置所有HSV饱和度（0.01~~1）																			   			--->>色彩纯净度
    void (*SetALLColor_HSV_S)(float setS);
    // 设置所有明度/亮度（0.01~~1）																							--->>也就是亮度
    void (*SetALLColor_HSV_V)(float setV);
#endif

    // 显示（发出数据）
    void (*show)(void);
} WS28xx_TypeStruct;

// typedef struct
// {
//     uint8_t cmd;
//     uint8_t bag_length;
//     uint8_t led_index;
//     uint8_t led_type;
//     uint8_t led_r;
//     uint8_t led_g;
//     uint8_t led_b;
//     uint8_t blink_time;
//     uint8_t led_hsv_v;
//     uint16_t old_crc;
//     uint16_t new_crc;
// } _led_cmd;

struct _ws_ctr
{
    uint8_t blink_times : 3; // 闪烁周期,单位20MS
    uint32_t user_rgb;
};

void ws2812_control(struct _ws_ctr *wsctr);

extern WS28xx_TypeStruct WS28xx;
extern struct _ws_ctr wsled_ctr;
/*
 *工具函数
 */
#define LIMIT(x, max, min) ((x < max) ? ((x > min) ? x : min) : max)
#define MAX(a, b, c) (a > b ? a : b > c ? b \
                                        : c)
#define MIN(a, b, c) (a < b ? a : b < c ? b \
                                        : c)
void RGB2HSV(unsigned char r, unsigned char g, unsigned char b, float *h, float *s, float *v);
void HSV2RGB(float h, float s, float v, unsigned char *r, unsigned char *g, unsigned char *b);

/****************************************************************************************/

// 获取某个位置的RGB
void __show(void);
void __SetPixelColor_RGB(unsigned short int index, unsigned char r, unsigned char g, unsigned char b);
void __GetPixelColor_RGB(unsigned short int index, unsigned char *r, unsigned char *g, unsigned char *b);
void __SetPixelColor_From_RGB_Buffer(unsigned short int pixelIndex, unsigned char pRGB_Buffer[][3], unsigned short int DataCount);
void __SetALLColor_RGB(unsigned char r, unsigned char g, unsigned char b);

#ifdef USE_HSV_WAYS
void RGB2HSV(unsigned char r, unsigned char g, unsigned char b, float *h, float *s, float *v);
void HSV2RGB(float h, float s, float v, unsigned char *r, unsigned char *g, unsigned char *b);
void __SetPixelColor_HSV(unsigned short int pixelIndex, unsigned short int h, float s, float v);
void __SetPixelColor_HSV_H(unsigned short int pixelIndex, unsigned short int setH);
void __SetPixelColor_HSV_S(unsigned short int pixelIndex, float setS);
void __SetPixelColor_HSV_V(unsigned short int pixelIndex, float setV);
void __SetALLColor_HSV_H(unsigned short int setH);
void __SetALLColor_HSV_S(float setS);
void __SetALLColor_HSV_V(float setV);
#endif

void ws2812_set(uint8_t blink, uint32_t color);

#endif
